package controller

import (
	"awesomeProject/lib"
	"log"
)

func BuildFriendMsg(data *map[string]interface{}) error {
	content, err := HandleFriendMsg(data)
	log.Println(content)
	conn, ok := clients[content.Self.Id]
	if !ok {
		log.Println("acceptor is offline")
	}
	targetConn, ok := clients[content.TheOther.Id]
	if !ok {
		log.Println(content.TheOther.Id)
		log.Println("the other is offline")
	}
	if err != nil {
		return err
	}
	if content.IsAcceptedCode == 1 {

		if err := targetConn.WriteJSON(lib.AddFriendFailOrSuccess{
			Message:  "he/she refuse your request",
			Type:     "add_friend_fail_or_success",
			TheOther: content.Self,
		}); err != nil {
			log.Println("write json to targetConn fail")
			return err
		}
		return nil
	} else if content.IsAcceptedCode == 0 {
		log.Println("0 is invalid, don't use")
		return nil
	}
	if err := AddRelation(content.Self.Id, content.TheOther.Id); err != nil {

		if err := conn.WriteJSON(lib.AddFriendFailOrSuccess{
			Message:  "好友请求发送失败，请重新尝试",
			Type:     "add_friend_fail_or_success",
			TheOther: content.TheOther,
		}); err != nil {
			log.Println("send fail message fail in build friend")
			return err
		}
		return err
	}
	err = conn.WriteJSON(lib.AddFriendFailOrSuccess{
		Message:  "添加好友成功！",
		Type:     "add_friend_fail_or_success",
		TheOther: content.TheOther,
	})
	err = targetConn.WriteJSON(lib.AddFriendFailOrSuccess{
		Message:  "添加好友成功！",
		Type:     "add_friend_fail_or_success",
		TheOther: content.Self,
	})
	if err != nil {
		log.Println("send success message fail in build friend")
		return err
	}
	return nil
}

func AddRelation(id1 int64, id2 int64) error {
	stmt, err := pool.Prepare("insert into public.relation(id_1, id_2) values ($1, $2)")
	if err != nil {
		log.Println("statement build fail in add relation")
		return err
	}
	if _, err := stmt.Exec(id1, id2); err != nil {
		log.Println("database fail in add relation")
		return err
	}
	if _, err := stmt.Exec(id2, id1); err != nil {
		log.Println("database fail in add relation")
		return err
	}
	return nil
}

func StoreFrdReq(req lib.AddFriendReq) error {
	_, ok, err := SearchId(req.ReceiverId)
	if !ok || err != nil {
		return err
	}
	stmt, err := pool.Prepare("insert into public.uc_friend_req(sender_id, sender_username, sender_photo, sender_gender, receiver_id, brief, is_checked) values ($1, $2, $3, $4, $5, $6, false)")
	if err != nil {
		log.Println("prepare stmt fail in store friend req")
		return err
	}
	_, err = stmt.Exec(
		req.Sender.Id,
		req.Sender.Username,
		req.Sender.Photo,
		req.Sender.Gender,
		req.ReceiverId,
		req.Brief,
	)
	if err != nil {
		log.Println("exec stmt fail in store friend req", err)
		return err
	}
	return nil
}

func PullFrdReq(id int64) ([]lib.GetFriendReqMsg, int) {
	var msgs []lib.GetFriendReqMsg
	rows, err := pool.Query("update public.uc_friend_req set is_checked=true where is_checked=false and receiver_id=$1 "+
		"returning sender_id, sender_username, sender_photo, sender_gender, receiver_id, brief", id)
	if err != nil {
		return msgs, 0
	}
	cnt := 0
	for rows.Next() {
		msg := lib.GetFriendReqMsg{}
		rows.Scan(&msg.Sender.Id,
			&msg.Sender.Username,
			&msg.Sender.Photo,
			&msg.Sender.Gender,
			&msg.SelfId,
			&msg.Brief,
		)
		cnt++
		msgs = append(msgs, msg)
	}
	return msgs, cnt
}
